import 'reflect-metadata';
// Load environment variables FIRST before any other imports
import dotenv from 'dotenv';
import path from 'path';
const fs = require('fs');

// Load environment variables based on NODE_ENV
const nodeEnv = process.env.NODE_ENV || 'development';
console.log(`🔍 NODE_ENV detected: ${nodeEnv}`);
const envFile = path.resolve(process.cwd(), `.env.${nodeEnv}`);
const defaultEnvFile = path.resolve(process.cwd(), '.env');
console.log(`🔍 Looking for env file: ${envFile}`);

// Try to load environment-specific file first, fallback to .env
if (fs.existsSync(envFile)) {
  dotenv.config({ path: envFile });
  console.log(`✅ Loaded environment variables from .env.${nodeEnv}`);
} else {
  console.log(`⚠️  Could not find .env.${nodeEnv}, falling back to .env`);
  dotenv.config({ path: defaultEnvFile });
}

// Now import other modules after environment variables are loaded
import express, { Application } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import swaggerUi from 'swagger-ui-express';
import { swaggerSpec } from './config/swagger';
import { initializeAIProviders } from './config/ai';
import { errorHandler } from './middleware/errorHandler';
import { notFound } from './middleware/notFound';
import { initializeDatabase } from './config/database';
import apiRoutes from './routes/api';
import userRoutes from './routes/userRoutes';
import postRoutes from './routes/postRoutes';
import paymentRoutes from './routes/paymentRoutes';
import testRoutes from './routes/test';

class Server {
  private app: Application;
  private port: string | number;

  constructor() {
    this.app = express();
    this.port = process.env.PORT || 3001;
    this.initializeTemplateEngine();
    this.initializeMiddlewares();
    this.initializeRoutes();
    this.initializeErrorHandling();
  }

  private initializeTemplateEngine(): void {
    // 设置EJS模板引擎
    this.app.set('view engine', 'ejs');
    this.app.set('views', path.join(__dirname, '../views'));
    
    // 设置静态文件目录（如果需要的话）
    this.app.use('/public', express.static(path.join(__dirname, '../public')));
  }

  private initializeMiddlewares(): void {
    // Security middleware
    this.app.use(helmet({
      contentSecurityPolicy: {
        directives: {
          defaultSrc: ["'self'"],
          styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com"],
          scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net", "https://accounts.google.com"],
          imgSrc: ["'self'", "data:", "https:"],
          connectSrc: ["'self'", "https://accounts.google.com"],
          frameSrc: ["'self'", "https://accounts.google.com"],
        },
      },
    }));
    
    // CORS middleware - 允许所有来源访问
    this.app.use(cors({
      origin: '*', // 允许所有来源
      credentials: false, // 当origin为*时，credentials必须为false
      methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
      allowedHeaders: ['Content-Type', 'Authorization', 'stripe-signature']
    }));
    
    // Logging middleware
    this.app.use(morgan('combined'));
    
    // Stripe webhook需要原始请求体，所以在这里特殊处理
    this.app.use('/api/payments/webhook', express.raw({ type: 'application/json' }));
    
    // Body parsing middleware
    this.app.use(express.json({ limit: '10mb' }));
    this.app.use(express.urlencoded({ extended: true, limit: '10mb' }));
  }

  private initializeRoutes(): void {
    // Health check endpoint
    /**
     * @swagger
     * /health:
     *   get:
     *     tags: [Health]
     *     summary: 健康检查
     *     description: 检查服务器运行状态
     *     responses:
     *       200:
     *         description: 服务器运行正常
     *         content:
     *           application/json:
     *             schema:
     *               type: object
     *               properties:
     *                 status:
     *                   type: string
     *                   example: OK
     *                 message:
     *                   type: string
     *                   example: Server is running
     *                 timestamp:
     *                   type: string
     *                   format: date-time
     *                 environment:
     *                   type: string
     *                   example: development
     *                 database:
     *                   type: string
     *                   example: MySQL with TypeORM
     */
    this.app.get('/health', (req, res) => {
      res.status(200).json({
        status: 'OK',
        message: 'Server is running',
        timestamp: new Date().toISOString(),
        environment: process.env.NODE_ENV || 'development',
        database: 'MySQL with TypeORM'
      });
    });

    // Swagger documentation
    this.app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
      customSiteTitle: 'Express TypeScript API Documentation',
      customCss: '.swagger-ui .topbar { display: none }',
    }));

    // 导出OpenAPI规范的API端点
    /**
     * @swagger
     * /api-docs.json:
     *   get:
     *     tags: [Documentation]
     *     summary: 导出OpenAPI规范（JSON格式）
     *     description: 获取完整的OpenAPI 3.0规范文档（JSON格式）
     *     produces:
     *       - application/json
     *     responses:
     *       200:
     *         description: OpenAPI规范JSON文档
     *         content:
     *           application/json:
     *             schema:
     *               type: object
     */
    this.app.get('/api-docs.json', (req, res) => {
      res.setHeader('Content-Type', 'application/json');
      res.setHeader('Content-Disposition', 'attachment; filename="openapi.json"');
      res.send(swaggerSpec);
    });

    /**
     * @swagger
     * /api-docs.yaml:
     *   get:
     *     tags: [Documentation]
     *     summary: 导出OpenAPI规范（YAML格式）
     *     description: 获取完整的OpenAPI 3.0规范文档（YAML格式）
     *     produces:
     *       - text/yaml
     *     responses:
     *       200:
     *         description: OpenAPI规范YAML文档
     *         content:
     *           text/yaml:
     *             schema:
     *               type: string
     */
    this.app.get('/api-docs.yaml', (req, res) => {
      const yaml = require('js-yaml');
      const yamlStr = yaml.dump(swaggerSpec);
      res.setHeader('Content-Type', 'text/yaml');
      res.setHeader('Content-Disposition', 'attachment; filename="openapi.yaml"');
      res.send(yamlStr);
    });

    // Test pages routes
    this.app.use('/test', testRoutes);

    // Privacy and Terms routes for Google OAuth compliance
    this.app.get('/privacy', (req, res) => {
      res.send(`
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>隐私政策 - Express TypeScript API</title>
          <style>
            body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; line-height: 1.6; }
            h1 { color: #333; }
            h2 { color: #555; margin-top: 30px; }
            .contact { background: #f5f5f5; padding: 15px; border-radius: 5px; margin-top: 20px; }
          </style>
        </head>
        <body>
          <h1>隐私政策</h1>
          <p><strong>最后更新日期：</strong> ${new Date().toLocaleDateString()}</p>
          
          <h2>概述</h2>
          <p>本应用（Express TypeScript API）仅用于开发测试目的。我们致力于保护您的隐私和个人信息安全。</p>
          
          <h2>收集的信息</h2>
          <p>当您使用Google登录时，我们可能收集以下信息：</p>
          <ul>
            <li>Google账号的基本资料信息（姓名、邮箱地址）</li>
            <li>公开的个人资料照片</li>
            <li>Google用户唯一标识符</li>
          </ul>
          
          <h2>信息使用</h2>
          <p>收集的信息仅用于：</p>
          <ul>
            <li>用户身份验证和授权</li>
            <li>提供个性化的用户体验</li>
            <li>应用功能的正常运行</li>
          </ul>
          
          <h2>信息共享</h2>
          <p>我们不会向第三方出售、交易或以其他方式转让您的个人信息，除非：</p>
          <ul>
            <li>获得您的明确同意</li>
            <li>法律要求或政府机关要求</li>
            <li>保护我们的权利、财产或安全</li>
          </ul>
          
          <h2>数据安全</h2>
          <p>我们采用适当的安全措施来保护您的个人信息，防止未经授权的访问、使用或披露。</p>
          
          <h2>联系我们</h2>
          <div class="contact">
            <p>如果您对本隐私政策有任何问题，请联系我们：</p>
            <p>邮箱: developer@example.com</p>
            <p>项目地址: <a href="https://github.com/your-repo">GitHub Repository</a></p>
          </div>
        </body>
        </html>
      `);
    });

    this.app.get('/terms', (req, res) => {
      res.send(`
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>服务条款 - Express TypeScript API</title>
          <style>
            body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; line-height: 1.6; }
            h1 { color: #333; }
            h2 { color: #555; margin-top: 30px; }
            .contact { background: #f5f5f5; padding: 15px; border-radius: 5px; margin-top: 20px; }
          </style>
        </head>
        <body>
          <h1>服务条款</h1>
          <p><strong>最后更新日期：</strong> ${new Date().toLocaleDateString()}</p>
          
          <h2>接受条款</h2>
          <p>通过访问和使用本应用（Express TypeScript API），您同意遵守这些服务条款。</p>
          
          <h2>服务描述</h2>
          <p>本应用是一个基于Express.js和TypeScript的后端API示例，提供以下功能：</p>
          <ul>
            <li>用户认证和授权（包括Google OAuth）</li>
            <li>RESTful API服务</li>
            <li>数据存储和管理</li>
            <li>API文档和测试界面</li>
          </ul>
          
          <h2>使用规则</h2>
          <p>您同意：</p>
          <ul>
            <li>仅将本服务用于合法目的</li>
            <li>不进行任何可能损害服务的行为</li>
            <li>不尝试未经授权访问系统或数据</li>
            <li>遵守所有适用的法律法规</li>
          </ul>
          
          <h2>免责声明</h2>
          <p>本应用仅用于开发测试目的，按"现状"提供，不提供任何明示或暗示的保证。</p>
          
          <h2>责任限制</h2>
          <p>在法律允许的最大范围内，我们不对因使用本服务而产生的任何直接、间接、偶然或后果性损害承担责任。</p>
          
          <h2>修改条款</h2>
          <p>我们保留随时修改这些条款的权利。修改后的条款将在发布后立即生效。</p>
          
          <h2>联系信息</h2>
          <div class="contact">
            <p>如果您对这些服务条款有任何问题，请联系我们：</p>
            <p>邮箱: developer@example.com</p>
            <p>项目地址: <a href="https://github.com/your-repo">GitHub Repository</a></p>
          </div>
        </body>
        </html>
      `);
    });

    // API routes
    this.app.use('/api', apiRoutes);
    this.app.use('/api/users', userRoutes);
    this.app.use('/api/posts', postRoutes);
    this.app.use('/api/payments', paymentRoutes);

    // Root endpoint
    /**
     * @swagger
     * /:
     *   get:
     *     tags: [Health]
     *     summary: API欢迎页
     *     description: 返回API基本信息和可用端点列表
     *     responses:
     *       200:
     *         description: API信息
     *         content:
     *           application/json:
     *             schema:
     *               type: object
     *               properties:
     *                 message:
     *                   type: string
     *                   example: Welcome to Express TypeScript API with MySQL
     *                 version:
     *                   type: string
     *                   example: 1.0.0
     *                 database:
     *                   type: string
     *                   example: MySQL with TypeORM
     *                 endpoints:
     *                   type: object
     *                   properties:
     *                     health:
     *                       type: string
     *                       example: /health
     *                     api:
     *                       type: string
     *                       example: /api
     *                     users:
     *                       type: string
     *                       example: /api/users
     *                     posts:
     *                       type: string
     *                       example: /api/posts
     *                     payments:
     *                       type: string
     *                       example: /api/payments
     *                     credits:
     *                       type: string
     *                       example: /api/v1/credits
     *                     docs:
     *                       type: string
     *                       example: /api-docs
     */
    this.app.get('/', (req, res) => {
      res.json({
        message: 'Welcome to Express TypeScript API with MySQL',
        version: '1.0.0',
        database: 'MySQL with TypeORM',
        endpoints: {
          health: '/health',
          api: '/api',
          users: '/api/users',
          posts: '/api/posts',
          payments: '/api/payments',
          credits: '/api/v1/credits',
          docs: '/api-docs'
        }
      });
    });
  }

  private initializeErrorHandling(): void {
    // 404 handler
    this.app.use(notFound);
    
    // Global error handler
    this.app.use(errorHandler);
  }

  public async listen(): Promise<void> {
    try {
      // Initialize database connection
      const dbConnected = await initializeDatabase();
      
      // Initialize AI providers
      initializeAIProviders();
      
      this.app.listen(this.port, () => {
        console.log(`🚀 Server is running on port ${this.port}`);
        console.log(`📊 Database: ${dbConnected ? 'MySQL with TypeORM (Connected)' : 'MySQL with TypeORM (Disconnected)'}`);
        console.log(`📍 Environment: ${process.env.NODE_ENV || 'development'}`);
        console.log(`🔗 Health check: http://localhost:${this.port}/health`);
        console.log(`📚 API Documentation: http://localhost:${this.port}/api-docs`);
        console.log(`📝 API Endpoints:`);
        console.log(`   Users: http://localhost:${this.port}/api/users`);
        console.log(`   Posts: http://localhost:${this.port}/api/posts`);
        console.log(`   Payments: http://localhost:${this.port}/api/payments`);
        if (!dbConnected) {
          console.log(`⚠️  Note: Database APIs will not work until database is properly configured`);
        }
      });
    } catch (error) {
      console.error('❌ Failed to start server:', error);
      process.exit(1);
    }
  }

  public getApp(): Application {
    return this.app;
  }
}

// Create and start server
const server = new Server();
server.listen().catch((error) => {
  console.error('❌ Failed to start server:', error);
  process.exit(1);
});

export default server;